"""
任务注册表 - 管理所有注册的任务函数
实现装饰器模式和单例模式
"""

import functools
from loguru import logger
from typing import Dict, Callable, Any, List, Optional
from app.models.task.task_data import TaskType


class TaskRegistry:
    """任务注册表 - 单例模式"""

    _instance = None
    _registry: Dict[str, Dict[str, Any]] = {}

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._registry = {}
        return cls._instance

    def register(
        self,
        func_name: Optional[str] = None,
        task_type: TaskType = TaskType.LIGHT,
        timeout: Optional[int] = None,
        max_retries: int = 3,
    ):
        """装饰器：注册任务函数"""

        def decorator(func: Callable):
            name = func_name or func.__name__

            # 注册任务信息
            self._registry[name] = {
                "func": func,
                "task_type": task_type,
                "timeout": timeout,
                "max_retries": max_retries,
                "doc": func.__doc__ or "",
            }

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                return func(*args, **kwargs)

            logger.info(f"注册任务函数: {name} (类型: {task_type.value})")
            return wrapper

        return decorator

    def get_function(self, func_name: str) -> Callable:
        """获取注册的函数"""
        if func_name not in self._registry:
            raise ValueError(f"未找到注册的函数: {func_name}")
        return self._registry[func_name]["func"]

    def get_task_info(self, func_name: str) -> Dict[str, Any]:
        """获取任务信息"""
        if func_name not in self._registry:
            raise ValueError(f"未找到注册的函数: {func_name}")
        return self._registry[func_name].copy()

    def list_registered_tasks(self) -> List[Dict[str, Any]]:
        """列出所有注册的任务"""
        tasks = []
        for name, info in self._registry.items():
            tasks.append(
                {
                    "name": name,
                    "type": info["task_type"].value,
                    "timeout": info["timeout"],
                    "max_retries": info["max_retries"],
                    "doc": info["doc"],
                }
            )
        return tasks

    def is_registered(self, func_name: str) -> bool:
        """检查函数是否已注册"""
        return func_name in self._registry


# 全局实例
task_registry = TaskRegistry()


# 装饰器快捷方式
def light_task(
    func_name: Optional[str] = None, timeout: Optional[int] = None, max_retries: int = 3
):
    """轻度任务装饰器"""
    return task_registry.register(func_name, TaskType.LIGHT, timeout, max_retries)


def heavy_task(
    func_name: Optional[str] = None, timeout: Optional[int] = None, max_retries: int = 3
):
    """重度任务装饰器"""
    return task_registry.register(func_name, TaskType.HEAVY, timeout, max_retries)


def scheduled_task(
    func_name: Optional[str] = None, timeout: Optional[int] = None, max_retries: int = 3
):
    """定时任务装饰器"""
    return task_registry.register(func_name, TaskType.SCHEDULED, timeout, max_retries)


def periodic_task(
    func_name: Optional[str] = None, timeout: Optional[int] = None, max_retries: int = 3
):
    """周期性任务装饰器"""
    return task_registry.register(func_name, TaskType.PERIODIC, timeout, max_retries)
